﻿/**************************************************************************
创建日期:	2019/7/14 19:35:52     
作	  者:	张存
邮 	  箱:	zhangcunliang@126.com
创建时间:	
Copyright (c)    ZhCun.cn

描	述： 进行web项目的全局配置
记	录：
***************************************************************************/
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ZhCun.Utils;
using ZhCun.WebCommon.AL;

namespace ZhCun.WebCommon
{
    public static class GlobalServiceConfig
    {
        /// <summary>
        /// 初始化默认全部服务配置
        /// </summary>
        public static IMvcBuilder InitServiceConfig(this IServiceCollection services, Action<SwaggerGenOptions> swaggerOption, Action<MvcJsonOptions> mvcJsonOption = null, Action<MvcOptions> setupAction = null)
        {
            services.AddSession();

            InitSwagger(services, swaggerOption);

            return
            services.AddMvc(o =>
            {
                o.Filters.Add<GlobalExceptionsFilter>(); //加入全局异常类
                setupAction?.Invoke(o);
            }).InitJsonOptions(mvcJsonOption); //全局配置,如果知道怎么把这个单独拿出来，就更改这块代码 2019.7.15;
        }

        /// <summary>
        /// 初始化Swagger
        /// </summary>
        public static IServiceCollection InitSwagger(this IServiceCollection services, Action<SwaggerGenOptions> setupAction)
        {
            return
            services.AddSwaggerGen(c =>
            {
                setupAction?.Invoke(c);

                c.OperationFilter<SwaggerOperationFilter>();

                c.DocumentFilter<SwaggerIgnoreFilter>();

                // 为 Swagger JSON and UI设置xml文档注释路径                
                //获取当前程序的
                var fileName = Assembly.GetEntryAssembly().Location;
                var path = Path.GetDirectoryName(fileName);
                var xmlFiles = AppCommonConfig.AppSettings.SwaggerXmlComments.Split(',');
                foreach (var xmlFile in xmlFiles)
                {
                    c.IncludeXmlComments(Path.Combine(path, xmlFile));
                }
            });
        }
        /// <summary>
        /// 初始化Json配置
        /// </summary>
        public static IMvcBuilder InitJsonOptions(this IMvcBuilder builder, Action<MvcJsonOptions> setupAction = null)
        {
            return
            builder.AddJsonOptions(options =>
            {
                //处理json到前台首字母小写的问题
                options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                setupAction?.Invoke(options);
            });
        }
        /// <summary>
        /// 初始化所有必须的配置项
        /// </summary>
        /// <param name="app"></param>
        /// <param name="setupAction"></param>
        public static void InitAppConfig(this IApplicationBuilder app, Action<SwaggerUIOptions> setupAction = null)
        {
            LoginStateCache.InitCache();            

            app.UseSession();
            InitExceptionHandler(app);
            InitMiddleware(app);
            InitSwaggerApp(app, setupAction);
        }
        /// <summary>
        /// 初始化swaggeer app
        /// </summary>
        public static void InitSwaggerApp(this IApplicationBuilder app, Action<SwaggerUIOptions> setupAction = null)
        {
            if (AppCommonConfig.AppSettings.SwaggerEnable)
            {
                var prefix = AppCommonConfig.AppSettings.SwaggerRoutePrefix;
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "swagger",
                        template: "/swagger");
                });

                //启用中间件服务生成Swagger作为JSON终结点
                app.UseSwagger();
                //启用中间件服务对swagger-ui，指定Swagger JSON终结点
                app.UseSwaggerUI(c =>
                {
                    setupAction?.Invoke(c);
                    //c.SwaggerEndpoint("/swagger/v1/swagger.json", "Test API");
                    //c.SwaggerEndpoint("/swagger/v2/swagger.json", "用户 API");
                    //c.SwaggerEndpoint("/swagger/v3/swagger.json", "业务 API");
                    c.RoutePrefix = $"{prefix}"; //如果在主页显示，则改为：Empty,区分大小写
                });
            }
        }
        /// <summary>
        /// 初始化常用中间件，目前未实现
        /// </summary>
        public static void InitMiddleware(this IApplicationBuilder app)
        {
            app.UseMiddleware<ErrorHandlingMiddleware>();

            //app.UseMiddleware<CommonMiddleware>();
        }
        /// <summary>
        /// 初始化全局异常处理handler
        /// </summary>
        public static void InitExceptionHandler(this IApplicationBuilder app)
        {
            app.UseExceptionHandler((builder) =>
            {
                builder.Run((context) =>
                {
                    return Task.Run(() =>
                    {
                        var feature = context.Features.Get<IExceptionHandlerFeature>();
                        var error = feature?.Error;
                        LogHelper.LogObj.Fatal("全局处理异常", error);
                    });
                });
            });
        }
    }
}